---
title: Building Custom Agents
description: Learn how to build custom agents using MCPClient and integrate tools with different agent frameworks
icon: "paintbrush"
---

# Building Custom Agents

MCP-Use provides flexible options for building custom agents that can utilize MCP tools. This guide will show you how to create your own agents by leveraging the existing adapters, particularly focusing on the LangChain adapter.

<Info>
**Why Build Custom Agents?** While MCP-Use provides a built-in `MCPAgent` class, custom agents give you maximum flexibility to integrate with existing systems, implement specialized behavior, or use different agent frameworks.
</Info>

## Overview

MCP-Use allows you to:

<CardGroup cols={3}>
  <Card title="Access Tools" icon="plug">
    Connect to powerful MCP tools through flexible connectors
  </Card>
  <Card title="Convert & Adapt" icon="arrows-rotate">
    Transform MCP tools to work with any agent framework via adapters
  </Card>
  <Card title="Build Agents" icon="robot">
    Create specialized agents tailored to your specific use cases
  </Card>
</CardGroup>

## Using the LangChain Adapter

The `LangChainAdapter` is a powerful component that converts MCP tools to LangChain tools, enabling you to use MCP tools with any LangChain-compatible agent.

<Note>
**Simplified API**: The LangChain adapter provides a streamlined API that handles all the complexity of session management, connector initialization, and tool conversion automatically.
</Note>

### Basic Example

Here's a simple example of creating a custom agent using the LangChain adapter:

<CodeGroup>
```typescript TypeScript
import { ChatOpenAI } from '@langchain/openai'
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents'
import { ChatPromptTemplate, MessagesPlaceholder } from '@langchain/core/prompts'
import { MCPClient, LangChainAdapter, loadConfigFile } from 'mcp-use'

async function main() {
    // Initialize the MCP client
    const config = await loadConfigFile('path/to/config.json')
    const client = new MCPClient(config)

    // Create adapter instance
    const adapter = new LangChainAdapter()

    // Get LangChain tools directly from the client with a single line
    const tools = await adapter.createTools(client)

    // Initialize your language model
    const llm = new ChatOpenAI({ model: 'gpt-4o' })

    // Create a prompt template
    const prompt = ChatPromptTemplate.fromMessages([
        ['system', 'You are a helpful assistant with access to powerful tools.'],
        new MessagesPlaceholder('chat_history'),
        ['human', '{input}'],
        new MessagesPlaceholder('agent_scratchpad'),
    ])

    // Create the agent
    const agent = createToolCallingAgent({ llm, tools, prompt })

    // Create the agent executor
    const agentExecutor = new AgentExecutor({ agent, tools, verbose: true })

    // Run the agent
    const result = await agentExecutor.invoke({ input: 'What can you do?' })
    console.log(result.output)

    await client.closeAllSessions()
}

main().catch(console.error)
```

```typescript TypeScript
import { ChatOpenAI } from '@langchain/openai'
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents'
import { ChatPromptTemplate, MessagesPlaceholder } from '@langchain/core/prompts'
import { MCPClient, LangChainAdapter, loadConfigFile } from 'mcp-use'

async function main() {
    // Initialize the MCP client
    const config = await loadConfigFile('path/to/config.json')
    const client = new MCPClient(config)

    // Create adapter instance
    const adapter = new LangChainAdapter()

    // Get LangChain tools directly from the client with a single line
    const tools = await adapter.createTools(client)

    // Initialize your language model
    const llm = new ChatOpenAI({ model: 'gpt-4o' })

    // Create a prompt template
    const prompt = ChatPromptTemplate.fromMessages([
        ['system', 'You are a helpful assistant with access to powerful tools.'],
        new MessagesPlaceholder('chat_history'),
        ['human', '{input}'],
        new MessagesPlaceholder('agent_scratchpad'),
    ])

    // Create the agent
    const agent = createToolCallingAgent({ llm, tools, prompt })

    // Create the agent executor
    const agentExecutor = new AgentExecutor({ agent, tools, verbose: true })

    // Run the agent
    const result = await agentExecutor.invoke({ input: 'What can you do?' })
    console.log(result.output)

    await client.closeAllSessions()
}

main().catch(console.error)
```
</CodeGroup>

<Tip>
**One-Line Tool Creation**: The API simplifies tool creation - all you need is to create an adapter instance and call its `create_tools` method:

<CodeGroup>
```typescript TypeScript
const adapter = new LangChainAdapter()
const tools = await adapter.createTools(client)
```

```typescript TypeScript
const adapter = new LangChainAdapter()
const tools = await adapter.createTools(client)
```
</CodeGroup>

You don't need to worry about sessions, connectors, or initialization. The adapter handles everything for you.
</Tip>

## Contributing New Adapters

<Info>
MCP-Use welcomes contributions for integrating with different agent frameworks! The adapter architecture is designed to make this process straightforward and requires minimal implementation effort.
</Info>

### Adapter Architecture

MCP-Use provides a `BaseAdapter` abstract class that handles most of the common functionality:

<CardGroup cols={2}>
  <Card title="Automatic Handling" icon="magic">
    - Tool caching management
    - Connector initialization
    - Multi-connector iteration
  </Card>
  <Card title="Simple Implementation" icon="code">
    Only implement `_convert_tool` method to convert MCP tools to your framework's format
  </Card>
</CardGroup>

<Warning>
**Single Required Method**: To create an adapter for a new framework, you only need to implement one method: `_convert_tool` to convert a single MCP tool to your framework's tool format.
</Warning>

### Creating a New Adapter

Here's a simple template for creating a new adapter:

### Using Your Custom Adapter

Once you've implemented your adapter, you can use it with the simplified API:

<CodeGroup>
```typescript TypeScript
import { YourFrameworkAdapter } from './your-module'
import { MCPClient, loadConfigFile } from 'mcp-use'

// Initialize the client
const config = await loadConfigFile('config.json')
const client = new MCPClient(config)

// Create an adapter instance
const adapter = new YourFrameworkAdapter()

// Get tools with a single line
const tools = await adapter.createTools(client)

// Use the tools with your framework
const agent = yourFramework.createAgent({ tools })
```

```typescript TypeScript
import { YourFrameworkAdapter } from './your-module'
import { MCPClient, loadConfigFile } from 'mcp-use'

// Initialize the client
const config = await loadConfigFile('config.json')
const client = new MCPClient(config)

// Create an adapter instance
const adapter = new YourFrameworkAdapter()

// Get tools with a single line
const tools = await adapter.createTools(client)

// Use the tools with your framework
const agent = yourFramework.createAgent({ tools })
```
</CodeGroup>

### Tips for Implementing an Adapter

<AccordionGroup>
  <Accordion title="Schema Conversion">
    Most frameworks have their own way of handling argument schemas. You'll need to convert the MCP tool's JSON Schema to your framework's format.

    <Tip>
    Look at the LangChain adapter implementation as a reference for handling schema conversion patterns.
    </Tip>
  </Accordion>

  <Accordion title="Tool Execution">
    When a tool is called in your framework, you'll need to pass the call to the connector's `call_tool` method and handle the result.

    <Warning>
    Always ensure proper async/await handling when calling MCP tools, as they are inherently asynchronous.
    </Warning>
  </Accordion>

  <Accordion title="Result Parsing">
    MCP tools return structured data with types like text, images, or embedded resources. Your adapter should parse these into a format your framework understands.
  </Accordion>

  <Accordion title="Error Handling">
    Ensure your adapter handles errors gracefully, both during tool conversion and execution.

    <Note>
    The base adapter provides logging utilities to help with error reporting and debugging.
    </Note>
  </Accordion>
</AccordionGroup>

## Conclusion

<CardGroup cols={2}>
  <Card title="Maximum Flexibility" icon="expand">
    Build specialized agents tailored to your specific tasks or integrate MCP capabilities into existing systems
  </Card>
  <Card title="Simple Architecture" icon="puzzle-piece">
    Easy extension with minimal implementation - just one `_convert_tool` method needed
  </Card>
</CardGroup>

<Info>
**Key Benefits:**
- **Simplified API**: Create tools directly from MCPClient with a single method call
- **Automatic Management**: Session and connector complexity is handled automatically
- **Flexible Integration**: Works with any agent framework that has a LangChain-style interface
</Info>

<Tip>
**Contributing Back**: We welcome contributions to expand the adapter ecosystem! If you develop an adapter for a new framework, please consider contributing it back to the project to help the community.
</Tip>
